/**
 * 基于原生websocket， 封装socket方法
 *
 */
import { useUserStore } from '../stores/user';

interface ISocket {
  websocket: any
  connectURL: Array<string>
  socketOpen: boolean
  heartbeatTimer: any
  heartbeatInterval: number
  heartbeatCount: number
  heartbeatCurrent: number
  isReconnect: boolean
  reconnectCount: number
  reconnectCurrent: number
  reconnectTimer: any
  reconnectInterval: number
  init: (receiveMessage: Function | null) => any
  receive: (message: any) => void
  heartbeat: () => void
  send: (data: any) => void
  close: () => void
  reconnect: () => void
}

const thingSocket: ISocket = {
  // websocket 实例
  websocket: null,
  // 连接地址
  connectURL: [],
  // 开启标识
  socketOpen: false,
  // 心跳timer
  heartbeatTimer: null,
  // 心跳发送频率
  heartbeatInterval: 30000,
  // 异常跳动次数
  heartbeatCurrent: 0,
  // 允许最多异常跳动次数
  heartbeatCount: 3,
  // 是否自动重连
  isReconnect: true,
  // 重连次数
  reconnectCount: 5,
  // 已发起重连次数
  reconnectCurrent: 0,
  // 重连timer
  reconnectTimer: null,
  // 重连频率
  reconnectInterval: 5000,

  init: (receiveMessage: Function | null) => {
    // 检查当前浏览器是否支持 WebSocket
    if (!('WebSocket' in window)) {
      console.error('浏览器不支持WebSocket')
      return null
    }

    // 已经创建过连接不再重复创建
    // if (socket.websocket) {
    //   return socket.websocket
    // }

    // 连接地址

    thingSocket.connectURL = [`ws://${location.host}/api/websocket/connect?Authorization=${useUserStore().token
      }`, 'ws://10.100.50.50:3002?token=web']
    thingSocket.websocket = thingSocket.websocket || new WebSocket(thingSocket.connectURL[1])



    // 解说消息
    thingSocket.websocket.onmessage = (e: MessageEvent) => {
      const { data } = e




      // 心跳检测
      if (data === 'pong') {
        thingSocket.heartbeatCurrent = 0
        return
      }

      if (receiveMessage) {
        receiveMessage(data)
      }
    }

    // 连接成功
    thingSocket.websocket.onopen = (e: Event) => {
      console.log(`%c` + `THINGJSwebsocket连接成功` + ` is running`, `font-weight: bold; color: #ffb712; background:linear-gradient(-45deg, #bd34fe 50%, #47caff 50% );background: -webkit-linear-gradient( 120deg, #bd34fe 30%, #41d1ff );background-clip: text;-webkit-background-clip: text; -webkit-text-fill-color:linear-gradient( -45deg, #bd34fe 50%, #47caff 50% ); padding: 8px 12px; border-radius: 4px;`);
      thingSocket.socketOpen = true
      thingSocket.isReconnect = true
      // 开启心跳
      thingSocket.heartbeat()
    }

    // 连接发生错误
    thingSocket.websocket.onerror = (e: Event) => {

      console.log(`%c` + `THINGJSwebsocket连接失败` + ` is running`, `font-weight: bold; color: #ffb712; background:linear-gradient(-45deg, #bd34fe 50%, #47caff 50% );background: -webkit-linear-gradient( 120deg, #bd34fe 30%, #41d1ff );background-clip: text;-webkit-background-clip: text; -webkit-text-fill-color:linear-gradient( -45deg, #bd34fe 50%, #47caff 50% ); padding: 8px 12px; border-radius: 4px;`);
    }

    // 关闭连接
    thingSocket.websocket.onclose = (e: CloseEvent) => {

      console.log(`%c` + `THINGJSwebsocket断开连接` + ` is running`, `font-weight: bold; color: #ffb712; background:linear-gradient(-45deg, #bd34fe 50%, #47caff 50% );background: -webkit-linear-gradient( 120deg, #bd34fe 30%, #41d1ff );background-clip: text;-webkit-background-clip: text; -webkit-text-fill-color:linear-gradient( -45deg, #bd34fe 50%, #47caff 50% ); padding: 8px 12px; border-radius: 4px;`);
      clearInterval(thingSocket.heartbeatInterval)
      thingSocket.socketOpen = false
      thingSocket.websocket = null

      // 需要重新连接
      thingSocket.reconnect()
    }
  },

  send: data => {
    if (thingSocket.websocket && thingSocket.websocket.readyState === thingSocket.websocket.OPEN) {
      // 开启状态直接发送
      thingSocket.websocket.send(data)
    } else {
      // 重置心跳
      clearInterval(thingSocket.heartbeatTimer)
    }
  },

  receive: (message: any) => {
    let params = JSON.parse(JSON.parse(message.data).data)
    return params
  },

  heartbeat: () => {
    // 重置心跳
    if (thingSocket.heartbeatTimer) {
      clearInterval(thingSocket.heartbeatTimer)
    }
    thingSocket.heartbeatTimer = setInterval(() => {
      // 超过允许最多异常跳动次数视为断线, 重新连接
      if (thingSocket.heartbeatCurrent > thingSocket.heartbeatCount) {
        clearInterval(thingSocket.heartbeatTimer)
        thingSocket.heartbeatCurrent = 0
        thingSocket.reconnect()
      } else {
        thingSocket.send("ping")
        thingSocket.heartbeatCurrent++
      }
    }, thingSocket.heartbeatInterval)
  },

  // 关闭连接
  close: () => {
    clearInterval(thingSocket.heartbeatTimer)
    clearTimeout(thingSocket.reconnectTimer)
    thingSocket.isReconnect = false
    thingSocket.websocket && thingSocket.websocket.close()
  },

  // 重新连接
  reconnect: () => {
    if (thingSocket.isReconnect) {
      thingSocket.reconnectTimer = setTimeout(() => {
        // 超过重连次数
        if (thingSocket.reconnectCurrent >= thingSocket.reconnectCount) {
          clearTimeout(thingSocket.reconnectTimer)
          thingSocket.isReconnect = false
          return
        }
        // 记录重连次数
        thingSocket.reconnectCurrent++

        if (!thingSocket.isReconnect) {
          thingSocket.close()
        } else {
          console.log('websocket正在重新连接')
          console.log(`%c` + `THINGJSwebsocket正在重新连接` + ` is running`, `font-weight: bold; color: #ffb712; background:linear-gradient(-45deg, #bd34fe 50%, #47caff 50% );background: -webkit-linear-gradient( 120deg, #bd34fe 30%, #41d1ff );background-clip: text;-webkit-background-clip: text; -webkit-text-fill-color:linear-gradient( -45deg, #bd34fe 50%, #47caff 50% ); padding: 8px 12px; border-radius: 4px;`);
          thingSocket.init(null)
        }
      }, thingSocket.reconnectInterval)
    }
  }
}

export default thingSocket
